package fr.openwide.core.wicket.more.markup.html.list;
import java.util.List;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.navigation.paging.IPageableItems;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import fr.openwide.core.jpa.business.generic.model.GenericEntity;
import fr.openwide.core.jpa.exception.SecurityServiceException;
import fr.openwide.core.jpa.exception.ServiceException;
import fr.openwide.core.wicket.more.markup.html.action.AbstractAjaxAction;
import fr.openwide.core.wicket.more.markup.html.feedback.FeedbackUtils;
import fr.openwide.core.wicket.more.markup.html.link.InvisibleLink;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.confirm.component.AjaxConfirmLink;
import fr.openwide.core.wicket.more.markup.repeater.data.GenericEntityListModelDataProvider;
import fr.openwide.core.wicket.more.markup.repeater.data.OddEvenDataView;
import fr.openwide.core.wicket.more.model.ReadOnlyModel;
public abstract class AbstractGenericItemListPanel<T extends GenericEntity<Long, ?>> extends Panel {
private static final long serialVersionUID = 1L;
private IDataProvider<T> dataProvider;
private DataView<T> dataView;
public AbstractGenericItemListPanel(String id, long itemsPerPage) {
this(id, (IDataProvider<T>) null, itemsPerPage);
}
public AbstractGenericItemListPanel(String id, IModel<? extends List<T>> listModel, long itemsPerPage) {
this(id, new GenericEntityListModelDataProvider<Long, T>(listModel), itemsPerPage);
}
public AbstractGenericItemListPanel(String id, IDataProvider<T> dataProvider, long itemsPerPage) {
super(id);
this.setOutputMarkupId(true);
this.dataProvider = dataProvider;
dataView = new OddEvenDataView<T>("item", dataProvider, itemsPerPage) {
private static final long serialVersionUID = 8487422965167269031L;
@Override
protected void populateItem(final Item<T> item) {
final IModel<T> itemModel = item.getModel();
AbstractGenericItemListPanel.this.addItemColumns(item, itemModel);
item.add(getActionButtonsPanel("actionButtons", itemModel));
}
};
add(dataView);
add(new WebMarkupContainer("emptyList") {
private static final long serialVersionUID = 6700720373087584498L;
@Override
public boolean isVisible() {
return dataView.getDataProvider().size() == 0;
}
});
}
public void setModel(IModel<? extends List<T>> listModel) {
this.dataProvider = new GenericEntityListModelDataProvider<Long, T>(listModel);
}
@Override
public void detachModels() {
super.detachModels();
if (dataProvider != null) {
dataProvider.detach();
}
if (dataView != null) {
dataView.detach();
}
}
protected Panel getActionButtonsPanel(String wicketId, IModel<T> itemModel) {
Panel actionButtons;
if (isAtLeastOneActionAvailable()) {
actionButtons = new AbstractGenericItemListActionButtons<T>(wicketId, itemModel) {
private static final long serialVersionUID = 1L;
@Override
protected MarkupContainer getActionLink(String id, IModel<? extends T> itemModel) {
MarkupContainer actionLink = AbstractGenericItemListPanel.this.getActionLink(id, itemModel);
if (!isActionAvailable()) {
getActionLinkHidden().setVisible(false);
return new InvisibleLink<Void>(id);
} else {
boolean actionVisible = actionLink.isVisible();
actionLink.setVisible(actionVisible);
getActionLinkHidden().setVisible(!actionVisible);
}
return actionLink;
}
@Override
protected MarkupContainer getEditLink(String id, IModel<? extends T> itemModel) {
if (!isEditAvailable()) {
getEditLinkHidden().setVisible(false);
return new InvisibleLink<Void>(id);
} else {
MarkupContainer editLink = AbstractGenericItemListPanel.this.getEditLink(id, itemModel);
boolean editVisible = editLink.isVisible()
&& AbstractGenericItemListPanel.this.hasWritePermissionOn(itemModel);
editLink.setVisible(editVisible);
getEditLinkHidden().setVisible(!editVisible);
return editLink;
}
}
@Override
protected MarkupContainer getDeleteLink(String id, IModel<? extends T> itemModel) {
if (!isDeleteAvailable()) {
getDeleteLinkHidden().setVisible(false);
return new InvisibleLink<Void>(id);
} else {
MarkupContainer deleteLink = AbstractGenericItemListPanel.this.getDeleteLink(id, itemModel);
boolean deleteVisible = deleteLink.isVisible()
&& AbstractGenericItemListPanel.this.hasWritePermissionOn(itemModel);
deleteLink.setVisible(deleteVisible);
getDeleteLinkHidden().setVisible(!deleteVisible);
return deleteLink;
}
}
@Override
protected IModel<String> getActionText(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getActionText(itemModel);
}
@Override
protected IModel<String> getActionBootstrapIconClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getActionBootstrapIconClass(itemModel);
}
@Override
protected IModel<String> getActionBootstrapIconColorClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getActionBootstrapIconColorClass(itemModel);
}
@Override
protected IModel<String> getActionBootstrapColorClass(IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getActionBootstrapColorClass(itemModel);
}
@Override
protected IModel<String> getEditText(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getEditText(itemModel);
}
@Override
protected IModel<String> getEditBootstrapIconClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getEditBootstrapIconClass(itemModel);
}
@Override
protected IModel<String> getEditBootstrapIconColorClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getEditBootstrapIconColorClass(itemModel);
}
@Override
protected IModel<String> getEditBootstrapColorClass(IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getEditBootstrapColorClass(itemModel);
}
@Override
protected IModel<String> getDeleteText(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getDeleteText(itemModel);
}
@Override
protected IModel<String> getDeleteBootstrapIconClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getDeleteBootstrapIconClass(itemModel);
}
@Override
protected IModel<String> getDeleteBootstrapIconColorClass(final IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getDeleteBootstrapIconColorClass(itemModel);
}
@Override
protected IModel<String> getDeleteBootstrapColorClass(IModel<? extends T> itemModel) {
return AbstractGenericItemListPanel.this.getDeleteBootstrapColorClass(itemModel);
}
};
} else {
actionButtons = new EmptyPanel(wicketId);
actionButtons.setVisible(false);
}
return actionButtons;
}
protected MarkupContainer getDeleteLink(String id, final IModel<? extends T> itemModel) {
return AjaxConfirmLink.<T>build()
.title(getDeleteConfirmationTitleModel(itemModel))
.content(getDeleteConfirmationTextModel(itemModel))
.yes(getDeleteConfirmationYesLabelModel(itemModel))
.no(getDeleteConfirmationNoLabelModel(itemModel))
.onClick(new AbstractAjaxAction() {
private static final long serialVersionUID = 1L;
@Override
public void execute(AjaxRequestTarget target) {
try {
doDeleteItem(itemModel);
Session.get().success(getString("common.delete.success"));
} catch (Exception e) {
Session.get().error(getString("common.delete.error"));
}
target.add(getPage());
dataProvider.detach();
FeedbackUtils.refreshFeedback(target, getPage());
}
})
.create(id, ReadOnlyModel.of(itemModel));
}
protected IModel<String> getDeleteConfirmationTitleModel(IModel<? extends T> itemModel) {
return new ResourceModel("common.confirmTitle");
}
protected IModel<String> getDeleteConfirmationTextModel(IModel<? extends T> itemModel) {
return new ResourceModel("common.deleteConfirmation");
}
protected IModel<String> getDeleteConfirmationYesLabelModel(IModel<? extends T> itemModel) {
return new ResourceModel("common.confirm");
}
protected IModel<String> getDeleteConfirmationNoLabelModel(IModel<? extends T> itemModel) {
return new ResourceModel("common.cancel");
}
protected abstract boolean hasWritePermissionOn(IModel<? extends T> itemModel);
protected DataView<T> getDataView() {
return dataView;
}
public IPageableItems getPageable() {
return dataView;
}
protected abstract void addItemColumns(final Item<T> item, final IModel<? extends T> itemModel);
protected MarkupContainer getActionLink(final String id, final IModel<? extends T> itemModel) {
return new InvisibleLink<Void>(id);
}
protected IModel<String> getActionText(final IModel<? extends T> itemModel) {
return new ResourceModel("common.portfolio.action.viewDetails");
}
protected IModel<String> getActionBootstrapIconClass(final IModel<? extends T> itemModel) {
return Model.of("icon-search fa fa-search fa-fw");
}
/**
* <code>icon-white</code> ou rien
*
* @param itemModel
* @return
*/
protected IModel<String> getActionBootstrapIconColorClass(IModel<? extends T> itemModel) {
return Model.of("icon-white");
}
/**
* <code>btn-primary</code>, <code>btn-danger</code>, <code>btn-success</code>, etc.
*
* @param itemModel
* @return
*/
protected IModel<String> getActionBootstrapColorClass(IModel<? extends T> itemModel) {
return Model.of("btn-primary");
}
protected MarkupContainer getEditLink(final String id, final IModel<? extends T> itemModel) {
return new InvisibleLink<Void>(id);
}
protected IModel<String> getEditText(final IModel<? extends T> itemModel) {
return new ResourceModel("common.itemList.action.edit");
}
protected IModel<String> getEditBootstrapIconClass(final IModel<? extends T> itemModel) {
return Model.of("icon-pencil fa fa-pencil fa-fw");
}
/**
* <code>icon-white</code> ou rien
*
* @param itemModel
* @return
*/
protected IModel<String> getEditBootstrapIconColorClass(IModel<? extends T> itemModel) {
return Model.of("icon-white");
}
/**
* <code>btn-primary</code>, <code>btn-danger</code>, <code>btn-success</code>, etc.
*
* @param itemModel
* @return
*/
protected IModel<String> getEditBootstrapColorClass(IModel<? extends T> itemModel) {
return Model.of("btn-primary");
}
protected IModel<String> getDeleteText(final IModel<? extends T> itemModel) {
return new ResourceModel("common.itemList.action.delete");
}
protected IModel<String> getDeleteBootstrapIconClass(final IModel<? extends T> itemModel) {
return Model.of("icon-trash fa fa-trash-o fa-fw");
}
/**
* <code>icon-white</code> ou rien
*
* @param itemModel
* @return
*/
protected IModel<String> getDeleteBootstrapIconColorClass(IModel<? extends T> itemModel) {
return Model.of("icon-white");
}
/**
* <code>btn-primary</code>, <code>btn-danger</code>, <code>btn-success</code>, etc.
*
* @param itemModel
* @return
*/
protected IModel<String> getDeleteBootstrapColorClass(IModel<? extends T> itemModel) {
return Model.of("btn-danger");
}
protected abstract void doDeleteItem(final IModel<? extends T> itemModel) throws ServiceException,
SecurityServiceException;
protected boolean isAtLeastOneActionAvailable() {
return isActionAvailable() || isDeleteAvailable() || isEditAvailable();
}
protected abstract boolean isActionAvailable();
protected abstract boolean isDeleteAvailable();
protected abstract boolean isEditAvailable();
}